<template>
  <div class="el-image">
    <slot v-if="loading" name="placeholder">
      <div class="el-image__placeholder"></div>
    </slot>
    <slot v-else-if="error" name="error">
      <a v-if="message" :href="message" target="_blank">{{message}}</a>
      <div v-else class="el-image__error">{{ t('el.image.error') }}</div>
    </slot>
    <img
      v-else
      class="el-image__inner"
      v-bind="$attrs"
      v-on="$listeners"
      @click="clickHandler"
      :src="src"
      :style="imageStyle"
      :class="{ 'el-image__inner--center': alignCenter, 'el-image__preview': preview }">
    <div id="bigImage" class="imageBox" v-if="preview && showViewer" :style="{ 'z-index': zIndex }">
      <!-- 关闭按钮 -->
      <div class="actionIcon closeimg" v-show="dragbarShow" @click.stop="closeBigImage">
        <i class="iconfont icon-qiapianshangdeguanbi"></i>
      </div>
      <!-- 最小化 -->
      <!-- <div class="actionIcon minimg" v-show="!smallMode && dragbarShow" @click.stop="small">
        <i class="iconfont icon-zuixiaohua"></i>
      </div> -->
      <!-- 最大化 -->
      <!-- <div class="actionIcon minimg" v-show="smallMode && dragbarShow" @click.stop="maxMode">
        <i class="iconfont icon-zuidahua"></i>
      </div> -->
      <!-- 拖拽 -->
      <div id="ReplaydragbarImage" class="ReplaydragbarImage"></div>
      <image-viewer domId="bigImage" :z-index="zIndex" :on-close="closeViewer" :url-list="previewSrcList"/>
    </div>
  </div>
</template>

<script>
  import ImageViewer from './image-viewer'
  import Locale from 'element-ui/src/mixins/locale'
  import { on, off, getScrollContainer, isInContainer } from 'element-ui/src/utils/dom'
  import { isString, isHtmlElement } from 'element-ui/src/utils/types'
  import throttle from 'throttle-debounce/throttle'
  import popoverNovice from '@/components/public-modules/novice-boot/popoverNovice.vue'
  import bus from '@/store/eventBus'
  let imgWidth, imgHeight
  window.onresize = function () {
    imgWidth = document.body.clientWidth
    imgHeight = document.body.clientHeight
  }

  const isSupportObjectFit = () => document.documentElement.style.objectFit !== undefined

  const ObjectFit = {
    NONE: 'none',
    CONTAIN: 'contain',
    COVER: 'cover',
    FILL: 'fill',
    SCALE_DOWN: 'scale-down'
  }

  export default {
    name: 'webchatBigImage',

    mixins: [Locale],
    inheritAttrs: false,

    components: {
      ImageViewer,
      popoverNovice,
      bus
    },

    props: {
      src: String,
      chatMsgId: {
        type: String,
        default: ''
      },
      message: String,
      fit: String,
      lazy: Boolean,
      scrollContainer: {},
      previewSrcList: {
        type: Array,
        default: () => []
      },
      msgId: {
        type: String,
        default: ''
      },
      zIndex: {
        type: Number,
        default: 2000
      }
    },

    data () {
      return {
        loading: true,
        error: false,
        show: !this.lazy,
        imageWidth: 0,
        imageHeight: 0,
        showViewer: false,
        params: {
          left: 0,
          top: 0,
          currentX: 0,
          currentY: 0,
          flag: false
        },
        smallMode: false,
        dragbarShow: false
      }
    },

    computed: {
      imageStyle () {
        const { fit } = this
        if (!this.$isServer && fit) {
          return isSupportObjectFit()
            ? { 'object-fit': fit }
            : this.getImageStyle(fit)
        }
        return {}
      },
      alignCenter () {
        return !this.$isServer && !isSupportObjectFit() && this.fit !== ObjectFit.FILL
      },
      preview () {
        const { previewSrcList } = this
        return Array.isArray(previewSrcList) && previewSrcList.length > 0
      }
    },

    watch: {
      src (val) {
        this.show && this.loadImage()
      },
      show (val) {
        val && this.loadImage()
      }
    },

    mounted () {
      if (this.lazy) {
        this.addLazyLoadListener()
      } else {
        this.loadImage()
      }
    },

    beforeDestroy () {
      this.lazy && this.removeLazyLoadListener()
    },

    methods: {
      loadImage () {
        if (this.$isServer) return

        // reset status
        this.loading = true
        this.error = false

        const img = new Image()
        img.onload = e => this.handleLoad(e, img)
        img.onerror = this.handleError.bind(this)

        // bind html attrs
        // so it can behave consistently
        Object.keys(this.$attrs)
          .forEach((key) => {
            const value = this.$attrs[key]
            img.setAttribute(key, value)
          })
        img.src = this.src
      },
      handleLoad (e, img) {
        this.imageWidth = img.width
        this.imageHeight = img.height
        this.loading = false
      },
      handleError (e) {
        this.loading = false
        this.error = true
        this.$emit('error', e)
        this.$emit('imageLoadError', this.chatMsgId)
      },
      handleLazyLoad () {
        if (isInContainer(this.$el, this._scrollContainer)) {
          this.show = true
          this.removeLazyLoadListener()
        }
      },
      addLazyLoadListener () {
        if (this.$isServer) return

        const { scrollContainer } = this
        let _scrollContainer = null

        if (isHtmlElement(scrollContainer)) {
          _scrollContainer = scrollContainer
        } else if (isString(scrollContainer)) {
          _scrollContainer = document.querySelector(scrollContainer)
        } else {
          _scrollContainer = getScrollContainer(this.$el)
        }

        if (_scrollContainer) {
          this._scrollContainer = _scrollContainer
          this._lazyLoadHandler = throttle(200, this.handleLazyLoad)
          on(_scrollContainer, 'scroll', this._lazyLoadHandler)
          this.handleLazyLoad()
        }
      },
      removeLazyLoadListener () {
        const { _scrollContainer, _lazyLoadHandler } = this

        if (this.$isServer || !_scrollContainer || !_lazyLoadHandler) return

        off(_scrollContainer, 'scroll', _lazyLoadHandler)
        this._scrollContainer = null
        this._lazyLoadHandler = null
      },
      /**
       * simulate object-fit behavior to compatible with IE11 and other browsers which not support object-fit
       */
      getImageStyle (fit) {
        const { imageWidth, imageHeight } = this
        const {
          clientWidth: containerWidth,
          clientHeight: containerHeight
        } = this.$el

        if (!imageWidth || !imageHeight || !containerWidth || !containerHeight) return {}

        const vertical = imageWidth / imageHeight < 1

        if (fit === ObjectFit.SCALE_DOWN) {
          const isSmaller = imageWidth < containerWidth && imageHeight < containerHeight
          fit = isSmaller ? ObjectFit.NONE : ObjectFit.CONTAIN
        }

        switch (fit) {
          case ObjectFit.NONE:
            return { width: 'auto', height: 'auto' }
          case ObjectFit.CONTAIN:
            return vertical ? { width: 'auto' } : { height: 'auto' }
          case ObjectFit.COVER:
            return vertical ? { height: 'auto' } : { width: 'auto' }
          default:
            return {}
        }
      },
      clickHandler () {
        this.showViewer = true
        imgWidth = document.body.clientWidth
        imgHeight = document.body.clientHeight
        this.$nextTick(() => {
          let oContent = document.getElementById('bigImage')
          let oBar = document.getElementById('ReplaydragbarImage')
          this.startDrag(oBar, oContent, this)
          this.dragBarOver()
        })
      },
      closeBigImage () {
        this.showViewer = false
      },
      getPosTop () { // 获取图片定位的位置
        let imgHeight = this.$refs.imgheigth.height // 图片高度
        let imgWidth = this.$refs.imgheigth.width // 图片宽度
        return (imgWidth - imgHeight) / 2
      },
      closeViewer () {
        this.showViewer = false
      },
      getCss (o, key) {
        return o[key]
      },
      startDrag (bar, target, self, callback) {
        bar.onmousedown = function (event) {
          event.preventDefault()
          if (self.getCss(target, 'offsetLeft') !== 'auto') {
            self.params.left = self.getCss(target, 'offsetLeft')
          }
          if (self.getCss(target, 'offsetTop') !== 'auto') {
            self.params.top = self.getCss(target, 'offsetTop')
          }
          self.params.flag = true
          if (!event) {
            event = window.event
            bar.onselectstart = function () {
              return false
            }
          }
          let e = event
          self.params.currentX = e.clientX
          self.params.currentY = e.clientY < 0 ? 0 : e.clientY
          self.mouseMove(target, callback, self)
        }
        target.onmouseup = function () {
          self.params.flag = false
          if (self.getCss(target, 'offsetLeft') !== 'auto') {
            self.params.left = self.getCss(target, 'offsetLeft')
          }
          if (self.getCss(target, 'offsetTop') !== 'auto') {
            self.params.top = self.getCss(target, 'offsetTop')
          }
          document.onmousemove = null
        }
      },
      mouseMove (target) {
        let self = this
        document.onmousemove = function (event) {
          let e = window.event
          let nowX = e.clientX
          let nowY = e.clientY
          let disX = 0
          let disY = 0
          if (self.params.flag) {
            let boxWidth = document.getElementById('bigImage').clientWidth
            disX = nowX - self.params.currentX
            disY = nowY - self.params.currentY
            // 判断上下左右的极限位置
            let limitLeft = (parseInt(self.params.left) + disX) > (imgWidth - boxWidth - 2) ? (imgWidth - boxWidth - 2) : (parseInt(self.params.left) + disX) < (100 - self.dragWidth) ? 100 - self.dragWidth : parseInt(self.params.left) + disX
            let limitTop = (parseInt(self.params.top) + disY) > (imgHeight - 34) ? (imgHeight - 34) : (parseInt(self.params.top) + disY) < 0 ? 0 : parseInt(self.params.top) + disY
            //  右侧靠边就停止，左侧可以无限进入
            if (limitLeft + boxWidth + 10 < document.body.clientWidth) {
              target.style.left = limitLeft + 'px'
              target.style.top = limitTop + 'px'
            }
          }
        }
      },
      // 更新新手引导展示状态
      updateGuidanceSuccess (status) {
        let guidance = this.$getCache('guidance')
        this.getNoviceKeyStatus = guidance || {'webchat_imageTurnPage': true} // 服务不对，或者是没有这个对象时，默认不显示。webchatSessionLocking为气泡的key
      },
      // 最小化
      // small () {
      //   this.smallMode = true
      //   let container = document.getElementById('bigImage')
      //   // 先隐藏
      //   container.style.opacity = '0'
      //   container.style.left = '0'
      //   container.style.top = '0'
      //   let self = this
      //   window.setTimeout(() => {
      //     let box = document.getElementById('bigImage')
      //     let container = document.getElementById('bigImage')
      //     let imgBox = document.getElementById('bigImgBoxImg')
      //     let width = document.body.clientWidth
      //     let height = document.body.clientHeight
      //     container.style.left = (width - box.clientWidth) / 2 + 'px'
      //     if (((height - container.clientHeight) / 2) > 0) {
      //       container.style.top = (height - container.clientHeight) / 2 + 'px'
      //     } else {
      //       container.style.top = '20px'
      //     }
      //     container.style.opacity = '1'
      //   }, 0)
      // },
      // 最大化
      // maxMode () {
      //   this.smallMode = false
      //   let container = document.getElementById('bigImage')
      //   container.style.opacity = '0'
      //   container.style.left = '0'
      //   container.style.top = '0'
      //   let self = this
      //   window.setTimeout(() => {
      //     let container = document.getElementById('bigImage')
      //     let imgBox = document.getElementById('bigImgBoxImg')
      //     let width = document.body.clientWidth
      //     let height = document.body.clientHeight
      //     container.style.left = (width - container.clientWidth) / 2 + 'px'
      //     if (((height - container.clientHeight) / 2) > 0) {
      //       container.style.top = (height - container.clientHeight) / 2 + 'px'
      //     } else {
      //       container.style.top = '20px'
      //     }
      //     container.style.opacity = '1'
      //   }, 0)
      // },
      // getImgFun (flag) { // 获取图片高度
      //   let imgBoxHeigth
      //   if (flag) {
      //     imgBoxHeigth = this.$refs.imgheigth.width
      //   } else {
      //     imgBoxHeigth = this.$refs.imgheigth.height
      //   }
      //   let arrorPane = document.getElementsByClassName('arrow')
      //   for (var i = 0; i < arrorPane.length; i++) {
      //     arrorPane[i].style.height = imgBoxHeigth + 'px'
      //   }
      // },
      dragBarOver () {
        let self = this
        let oContent = document.getElementById('bigImage')
        oContent.onmouseover = function () {
          self.dragbarShow = true
        }
        oContent.onmouseout = function () {
          self.dragbarShow = false
        }
      }
    },
    beforeMount () {
      this.updateGuidanceSuccess()
    },
  }
</script>
<style lang="stylus" scope>
@import "./../../../../assets/common.styl"
#bigImage
  position fixed
  top 16%
  right 16%
  bottom 16%
  left 16%
  width 68%
  height 68%
  overflow hidden
.imageBox
  background rgba(0,0,0,0.5)
  border-radius 5px
  border-top-width: 0
  .actionIcon
    position absolute
    top 3px
    cursor pointer
    z-index 2
    background #606266
    border-radius 50%
    height 30px
    width 30px
    text-align center
    line-height 30px
    opacity 0.8
    i
      font-size 16px
  .closeimg
    right 10px
    top 10px
    color #fff
  .minimg
    right 40px
  .maximg
    right 40px
  .rotate
    right 70px
    font-weight 600
  .ReplaydragbarImage
    width 100%
    height 24px
    opacity 0
    position absolute
    cursor move
    z-index 1
</style>